﻿using System;
using System.Collections.Generic;
using System.Data;
using System.Data.Entity;
using System.Data.SqlClient;
using System.Linq;
using System.Linq.Expressions;
using System.Text;
using System.Threading.Tasks;
using ZBJF.Warranty.Model.ViewModel.BaseQueryModel;

namespace ZBJF.Warranty.DAL.Repositories
{
    public partial class BaseRepository<T> where T : class
    {
        //EF上下文的实例,保证 线程内唯一
        //实例化EF框架
        //ZuCheEntities db=new ZuCheEntities();

        //获取当前线程内的上下文实例
        private DbContext db = EFContextFactory.GetCurrentDbContext();

        public T AddEntities(T entity)
        {
            db.Entry<T>(entity).State = EntityState.Added;
            //db.SaveChanges();
            return entity;
        }

        public bool UpdateEntities(T entity)
        {
            db.Set<T>().Attach(entity);
            db.Entry<T>(entity).State = EntityState.Modified;
            //db.Entry<T>(entity).State= EntityState.Unchanged;
            //return db.SaveChanges() > 0;
            return true;
        }

        public bool DeleteEntities(T entity)
        {
            db.Set<T>().Attach(entity);
            db.Entry<T>(entity).State = EntityState.Deleted;
            //return db.SaveChanges()>0

            return true;
        }

        public IQueryable<T> LoadEntities(Expression<Func<T, bool>> wherelambda)
        {
            return db.Set<T>().Where(wherelambda).AsQueryable();
        }

        public IQueryable<T> LoadPagerEntities<S>(int pageIndex, int pageSize, out int total,
            Expression<Func<T, bool>> whereLambda, List<OrderModelField> orderByExpression)//Expression<Func<T, S>>
        {

            //条件过滤
            var query = db.Set<T>().Where(whereLambda);

            //创建表达式变量参数
            var parameter = Expression.Parameter(typeof(T), "o");
            var hadOrderBy = false;
            if (orderByExpression != null && orderByExpression.Count > 0)
            {

                for (int i = 0; i < orderByExpression.Count; i++)
                {
                    //根据属性名获取属性
                    var property = typeof(T).GetProperty(orderByExpression[i].PropertyName);
                    //创建一个访问属性的表达式
                    if (property == null)
                        continue;
                    var propertyAccess = Expression.MakeMemberAccess(parameter, property);
                    var orderByExp = Expression.Lambda(propertyAccess, parameter);

                    //OrderBy
                    //OrderByDescending
                    //ThenBy
                    //ThenByDescending
                    string methodName = string.Empty;
                    if (i == 0)
                        methodName = orderByExpression[i].IsDESC ? "OrderByDescending" : "OrderBy";
                    else
                        methodName = orderByExpression[i].IsDESC ? "ThenByDescending" : "ThenBy";


                    MethodCallExpression resultExp = Expression.Call(typeof(Queryable), methodName,
                        new Type[] { typeof(T), property.PropertyType }, query.Expression, Expression.Quote(orderByExp));
                    query = query.Provider.CreateQuery<T>(resultExp);
                    hadOrderBy = true;
                }
            }
            if (!hadOrderBy)//如果没有传排序字段，则以第一列排序
            {
                var property = typeof(T).GetProperties()[0];

                var propertyAccess = Expression.MakeMemberAccess(parameter, property);
                var orderByExp = Expression.Lambda(propertyAccess, parameter);

                MethodCallExpression resultExp = Expression.Call(typeof(Queryable), "OrderBy",
                    new Type[] { typeof(T), property.PropertyType }, query.Expression, Expression.Quote(orderByExp));
                query = query.Provider.CreateQuery<T>(resultExp);
            }

            total = query.Count();

            return query.Skip((pageIndex - 1) * pageSize).Take(pageSize).AsQueryable();


            //var tempData = db.Set<T>().Where(whereLambda);

            //total = tempData.Count();

            //if (isAsc)
            //{
            //    tempData =
            //        tempData.OrderBy<T, S>(orderByLambda)
            //            .Skip<T>(pageSize * (pageIndex - 1))
            //            .Take<T>(pageSize);
            //}
            //else
            //{
            //    tempData =
            //        tempData.OrderByDescending<T, S>(orderByLambda)
            //            .Skip<T>(pageSize * (pageIndex - 1))
            //            .Take<T>(pageSize);
            //}

            //return tempData.AsQueryable();
        }
        public int ExcuteSql(string strSql, SqlParameter[] parameters)
        {
            return DAL.EFContextFactory.GetCurrentDbContext().Database.ExecuteSqlCommand(strSql, parameters);
        }

        public object ExecuteScalar(string strSql, SqlParameter[] parameters)
        {
            return DAL.EFContextFactory.GetCurrentDbContext().Database.ExecuteScalar(strSql, parameters);
        }
        public DataTable SqlQuery(string strSql, params SqlParameter[] parameters)
        {
            return DAL.EFContextFactory.GetCurrentDbContext().Database.SqlQueryForDataTatable(strSql, parameters);
        }
    }
}
